import 'package:flutter/material.dart';

import '../../button/kq_ink_well.dart';
import 'kq_base_cell_render.dart';

/// 文本单元格绘制器
class KqTextCellRender<T> extends KqBaseCellRender<KqTextCellConfig> {
  /// 单元格文本构建器，返回指定单元格文本内容
  final T Function(int row, int column) dataBuilder;

  /// 单元格点击监听
  final CellClickCallback? Function(int row, int column)? onTapBuilder;

  /// 单元格高亮构建器，返回需要高亮的行，列及颜色
  final HighLight? Function(int row, int column)? highLightBuilder;

  HighLight? _highLight;

  /// 文本绘制器，用于获取文本的尺寸指
  @protected
  TextPainter painter = TextPainter(textDirection: TextDirection.ltr);

  KqTextCellRender(this.dataBuilder,
      {super.cellConfigBuilder, this.onTapBuilder, this.highLightBuilder});

  @override
  Widget buildBody(BuildContext context, int row, int column, double width,
      double height, bool isLongPress) {
    KqTextCellConfig? config = cellConfigBuilder?.call(row, column);
    int? maxLine = config?.maxLines;
    TextOverflow? textOverflow = config?.textOverflow;
    bool? softWrap = config?.softWrap;
    if (maxLine == null) {
      if (config?.isMultiLine == true) {
        if (textOverflow == TextOverflow.ellipsis) {
          maxLine =
              height ~/ measureTextHeight("测", textStyle: config?.textStyle);
          softWrap ??= false;
        }
      }
    }

    Widget result = Text(
      getCellText(dataBuilder.call(row, column)),
      style: config?.textStyle,
      softWrap: softWrap,
      maxLines: maxLine,
      overflow: textOverflow,
    );

    var padding = config?.padding;
    if (padding != null) {
      result = Padding(padding: padding, child: result);
    }

    var alignment = config?.alignment;
    if (alignment != null) {
      result = SizedBox(
        width: width,
        height: height,
        child: Align(
          alignment: alignment,
          child: result,
        ),
      );
    }

    HighLight? highLight = highLightBuilder?.call(row, column);
    CellClickCallback? onTap = onTapBuilder?.call(row, column);
    var cellOnTap = buildCellOnTap(row, column, onTap, highLight);
    if (onTap == null) {
      return GestureDetector(
        onTap: cellOnTap,
        behavior: HitTestBehavior.opaque,
        child: result,
      );
    }

    return KqInkWell(
      onTap: cellOnTap,
      child: result,
    );
  }

  /// 处理单元格点击逻辑
  @protected
  GestureTapCallback? buildCellOnTap(
      int row, int column, CellClickCallback? onTap, HighLight? highLight) {
    return () {
      var change = highLight != _highLight;
      if (change) {
        updateTable(() {
          _highLight = highLight;
        });
      }
      onTap?.call(row, column);
    };
  }

  /// 测量指定文本高度值
  @protected
  double measureTextHeight(String text, {TextStyle? textStyle}) {
    painter.text = TextSpan(
      text: text,
      style: textStyle,
    );

    painter.layout();
    return painter.height;
  }

  @override
  Color? getBackground(
      int row, int column, bool isLongPress, KqTextCellConfig? config) {
    if (isLongPress) {
      return config?.longPressBackground ?? config?.background;
    }

    if (_highLight != null) {
      if (_highLight!.row == row || _highLight!.column == column) {
        return _highLight!.color;
      }
    }

    return config?.background;
  }

  /// 获取单元格文本内容
  @protected
  String getCellText(T t) {
    return t.toString();
  }
}

/// 单元格配置项
class KqTextCellConfig extends KqBaseCellConfig {
  /// 文本的样式
  TextStyle? textStyle;

  /// 文本是否多行显示，会自动根据单元格高度适配最大显示行数。如果设置了[maxLines]则此值无效
  bool isMultiLine;

  /// 设置文本最大显示行数
  int? maxLines;

  /// 文本显示不下时超出部分展示策略
  TextOverflow? textOverflow;

  /// 文本在单元格的对齐方式
  AlignmentGeometry? alignment;

  /// 单元格内边距
  EdgeInsetsGeometry? padding;

  /// 未指定[isMultiLine]为true或[maxLines]>1时，由此值觉得是否软换行
  final bool? softWrap;

  KqTextCellConfig({
    this.isMultiLine = false,
    this.textStyle,
    this.textOverflow,
    this.alignment,
    this.padding,
    this.maxLines,
    this.softWrap,
    super.borderWidth,
    super.borderColor,
    super.background,
    super.longPressBackground,
  });
}

/// 行列高亮数据
class HighLight {
  /// 高亮的颜色
  final Color color;

  /// 需要高亮的行
  final int? row;

  /// 需要高亮的列
  final int? column;

  HighLight(this.color, {this.row, this.column});

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is HighLight &&
          runtimeType == other.runtimeType &&
          color == other.color &&
          row == other.row &&
          column == other.column;

  @override
  int get hashCode => color.hashCode ^ row.hashCode ^ column.hashCode;

  @override
  String toString() {
    return 'HighLight{color: $color, row: $row, column: $column}';
  }
}

/// 单元格点击回调
typedef CellClickCallback = void Function(int row, int column);
